import chalk from 'chalk';
import readline from 'readline';
import stringWidth from 'string-width';
import process from "process";
import {DateUtil} from "./DateUtil.js";

export class ConsoleTable {


    constructor(type) {
        this.data = [];
        this.showHeader = false;
        // 状态颜色
        this.TABLE_STATUS = {
            success: chalk.green('●成功'),
            normal: chalk.green('●正常'),
            error: chalk.red('●异常'),
            warn: chalk.yellow('●警告'),
            wait: chalk.blue('●等待'),
            canceled: chalk.white('●取消'),
            un: chalk.white('●无'),
            running: chalk.cyan('●运行')
        };
        // 类型颜色
        this.TYPE_COLOR = {
            support: chalk.yellow('依赖'),
            app: chalk.cyan('应用'),
            jz: chalk.magenta('基座')
        };

        // 列宽配置
        this.COL_WIDTHS = {
            num: 3,
            type: 8,
            name: 26,
            buildStatus: 20,
            deployStatus: 20,
            sonarStatus: 35,
            runStatus: 25,
            time: 16,
            desc: 100
        };
    }

    pad(str, width) {
        const visibleLength = stringWidth(str);
        if (visibleLength > width) {
            let truncated = '';
            let len = 0;
            for (const char of str) {
                const charWidth = stringWidth(char);
                if (len + charWidth > width - 1) break;
                truncated += char;
                len += charWidth;
            }
            return truncated + '…';
        }
        return str + ' '.repeat(width - visibleLength);
    }

    printBorder() {
        const totalWidth = Object.values(this.COL_WIDTHS).reduce((a, b) => a + b, 0);
        console.log('-'.repeat(totalWidth));
    }

    printHeader() {
        if (this.showHeader) {
            return
        }
        this.showHeader = true;
        this.printBorder();
        let header =
            this.pad(' ', this.COL_WIDTHS.num) +
            this.pad('类型', this.COL_WIDTHS.type) +
            this.pad('服务', this.COL_WIDTHS.name) +
            this.pad('启动时间', this.COL_WIDTHS.time) +

            this.pad('描述', this.COL_WIDTHS.desc);

        switch (this.type) {
            case '依赖发布单':
                // 没有其他环节
                break;
            case '发布单':
                header = header +
                    this.pad('扫描', this.COL_WIDTHS.sonarStatus) +
                    this.pad('启动', this.COL_WIDTHS.runStatus);
                break
            case '普通发布':
                header = header +
                    this.pad('扫描', this.COL_WIDTHS.sonarStatus) +
                    this.pad('部署', this.COL_WIDTHS.deployStatus) +
                    this.pad('启动', this.COL_WIDTHS.runStatus);
                break
        }
        header = header +
            this.pad('更新时间', this.COL_WIDTHS.time) +
            this.pad('描述', this.COL_WIDTHS.desc);
        console.log(chalk.bold(header));
    }

    // 打印一行（新增或更新）
    printRow(row, index) {
        readline.cursorTo(process.stdout, 0, index + 3); // 表头占3行
        readline.clearLine(process.stdout, 0);
        let line =
            this.pad(String(index + 1), this.COL_WIDTHS.num) +
            this.pad(this.TYPE_COLOR[row.type] || row.type, this.COL_WIDTHS.type) +
            this.pad(row.name, this.COL_WIDTHS.name) +
            this.pad(this.TABLE_STATUS[row.buildStatus] + (row.buildDesc || ''), this.COL_WIDTHS.buildStatus);

        switch (this.type) {
            case '依赖发布单':
                // 没有其他环节
                break;
            case '发布单':
                line = line +
                    this.pad(this.TABLE_STATUS[row.sonarStatus] + (row.sonarDesc || ''), this.COL_WIDTHS.sonarStatus) +
                    this.pad(this.TABLE_STATUS[row.runStatus] + (row.runDesc || ''), this.COL_WIDTHS.runStatus) ;
                break
            case '普通发布':
                line = line +
                    this.pad(this.TABLE_STATUS[row.sonarStatus] + (row.sonarDesc || ''), this.COL_WIDTHS.sonarStatus) +
                    this.pad(this.TABLE_STATUS[row.deployStatus] + (row.deployDesc || ''), this.COL_WIDTHS.deployStatus) +
                    this.pad(this.TABLE_STATUS[row.runStatus] + (row.runDesc || ''), this.COL_WIDTHS.runStatus);
                break
        }
        line = line +
            this.pad(row.time, this.COL_WIDTHS.time) +
            this.pad((row.desc || ''), this.COL_WIDTHS.desc);
        process.stdout.write(line + '\n');
    }

    // 添加一行
    addRow(rowObj) {
        const index = this.data.length;
        this.data.push(rowObj);
        this.printRow(rowObj, index);
    }


    /**
     * 获取这行数据
     * @param appName
     * @return {*}
     */
    getRow(appName) {
        const index = this.data.findIndex(r => r.name === appName);
        return this.data[index];
    }

    // 更新一行
    updateRow(newRow) {
        const index = this.data.findIndex(r => r.name === newRow.name);
        if (index === -1) {
            console.error(`未找到服务: ${newRow.name}`);
            return;
        }
        this.data[index] = {...this.data[index], ...newRow};
        this.data[index].time = DateUtil.nowTime();
        this.printRow(this.data[index], index);
    }
}
